home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr20 / spr_cut.zip / CUTLST.C next >
C/C++ Source or Header  |  1995-03-11  |  9KB  |  406 lines

  1. /* ---------------------------------------------------- */
  2. /* SPRITE CUTTER UTILITY v2.0                           */
  3. /* by gaggi@cs.unibo.it                                 */
  4. /* ---------------------------------------------------- */
  5. /* CUTLST.C                                             */
  6. /* sprite cut management module                         */
  7. /* ---------------------------------------------------- */
  8.  
  9. #include <alloc.h>
  10. #include <stdio.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13.  
  14. #include "mouse.h"
  15. #include "graph13h.h"
  16.  
  17. /* ---------------------------------------------------- */
  18.  
  19. #include "interfac.h"
  20. #include "cutlst.h"
  21. #include "picview.h"
  22.  
  23. extern void error(unsigned, char *);
  24. extern void xor_rect(unsigned, unsigned, unsigned, unsigned, unsigned );
  25. extern void prepare_buffer(struct CUT *, unsigned char far *);
  26.  
  27. /* ---------------------------------------------------- */
  28.  
  29. #define MEM_ERR       1
  30. #define FILE_ERR      2
  31. #define LOAD_ERR      3
  32. #define SOURCE_ERR    4
  33.  
  34. #define CUT_COLOR     0x04
  35. #define CUT_SIZE      sizeof(struct CUT) - sizeof(struct CUT *)
  36.  
  37. /* ------------- Public Datas ------------------------- */
  38.  
  39. struct CUT *cut_list; /* Dynamic list containing all the cuts */
  40.  
  41. picture source_pic;   /* Source picture datas: palette and bitmap */
  42.  
  43. char source_name[MAXSTRINGLEN]; /* File name of the source picture */
  44.  
  45. unsigned char cut_x_size= 0x08, cut_y_size= 0x08; /* Sizes of the sprite */
  46.  
  47. /* ------------- Static datas ------------------------- */
  48.  
  49. static unsigned list_modified= 0;
  50.  
  51. static char lst_msg[]= "List modified.\rSave(y/n)?";
  52. static char IO_prompt[]= "LST name ...";
  53. static char SPR_prompt[]= "SPR file name ...";
  54.  
  55. /* ------------- static functions -------------------- */
  56.  
  57. static int load_cuts(int handle)
  58. /* Loads the list of cuts from file */
  59. {
  60.  struct CUT *crsr, **last= &cut_list;
  61.  register unsigned ret_val= 0;
  62.  
  63.  while ( !eof(handle) )
  64.  {
  65.   if ( !(*last= crsr= (struct CUT *)malloc(sizeof(struct CUT))) )
  66.      {
  67.       error(MEM_ERR, NULL);
  68.       ret_val= -1;
  69.       break;
  70.      };
  71.  
  72.   if ( read(handle, crsr, CUT_SIZE) != CUT_SIZE )
  73.      {
  74.       ret_val= -1;
  75.       error(LOAD_ERR, NULL);
  76.       break;
  77.      };
  78.  
  79.   last= &(crsr->next);
  80.  }
  81.  
  82.  if (*last) *last= NULL;
  83.  
  84.  close(handle);
  85.  list_modified= 0;
  86.  Draw_cuts();
  87.  return ret_val;
  88. }
  89.  
  90. static int write_cuts(FILE *dest)
  91. /* Writes the list of cuts to a file */
  92. {
  93.  struct CUT *crsr= cut_list;
  94.  
  95.  while (crsr)
  96.  {
  97.   fwrite(crsr, CUT_SIZE, 1, dest);
  98.   crsr= crsr->next;
  99.  };
  100.  
  101.  list_modified= 0;
  102.  return fclose(dest);
  103. }
  104.  
  105.  
  106. static void cut_number(unsigned x, unsigned y, unsigned number)
  107. /* Puts the ordinal number of cut on the screen at coordinates x, y */
  108. {
  109.  char temp[3];
  110.  
  111.  Curcol= 0;
  112.  Draw_box(x + 1, y + 1, 15, 7);
  113.  
  114.  Curcol= 15;
  115.  sprintf(temp, "%d", number);
  116.  OutText(x, y, temp);
  117. }
  118.  
  119. static void renumber_cut(struct CUT *start, unsigned counter)
  120. /* Renumbers all the cuts starting from the cut pointed by *start */
  121. /* and the number counter.                                        */
  122. {
  123.  unsigned char far *buffer;
  124.  register unsigned temp1= start->width;
  125.  register unsigned temp2= start->height;
  126.  
  127.  if (temp1 < 16 || temp2 < 16)         /* if the cut sizes are too small     */
  128.     {                                  /* the result of restoring image data */
  129.      Show_picture(&source_pic, NO_SET);/* to cancel cut number is unreadable */
  130.      Draw_cuts();                      /* so I redraw picture and all        */
  131.      return;                           /* the cuts                           */
  132.     };
  133.  
  134.  if (!(buffer= (char far *)farmalloc(temp1*temp2 + 2*sizeof(unsigned))))
  135.  /* If there's not enough memory just draw a black bar to cancel cut */
  136.  /* number ...                                 */
  137.     {
  138.      Curcol= 0;
  139.      Draw_box(start->x + 1, start->y + 1, 15, 7);
  140.     }
  141.  else { /* ... otherwise restore the original picture pixels */
  142.  
  143.        ((unsigned far *)buffer)[0]= temp1; /* Type cast on a Lvalue... ARGH! */
  144.        ((unsigned far *)buffer)[1]= temp2; /* Davoli, please forgive me!     */
  145.  
  146.        prepare_buffer(start, buffer);
  147.        put_area(start->x, start->y, buffer);/* Restores original image datas */
  148.        farfree(buffer);
  149.       };
  150.  
  151.  start= start->next;
  152.  
  153.  while (start) /* Now change the number of all remaining cuts */
  154.  {
  155.   cut_number(start->x, start->y, counter++);
  156.   start= start->next;
  157.  };
  158.  
  159. }
  160.  
  161. /* ------------- public functions ------------------- */
  162.  
  163. int load_source(char *file_name)
  164. {
  165.  char *temp;
  166.  
  167.  if (cut_list) save_LST(1);
  168.  
  169.  temp= (char *)malloc(MAXSTRINGLEN);
  170.  
  171.  if (file_name) strcpy(temp, file_name);
  172.  else if (Input_box("PCX file name ...", temp, MAXSTRINGLEN - 1, 30, 80) <= 0)
  173.          {
  174.           free(temp);
  175.           return -1;
  176.          };
  177.  
  178.  switch ( PCX_load(temp, &source_pic) )
  179.  {
  180.   case 1:
  181.          error(FILE_ERR, temp);
  182.          free(temp);
  183.          return -1;
  184.  
  185.   case EOF:
  186.   case 2:
  187.          error(LOAD_ERR, NULL);
  188.          *source_name= 0;
  189.          destroy_LST();
  190.          clear_video(0);
  191.          free(temp);
  192.          return -1;
  193.  };
  194.  
  195.  destroy_LST();
  196.  strcpy(source_name, temp);
  197.  
  198.  mouse_cursor(OFF);
  199.  Show_picture(&source_pic, SET);
  200.  mouse_cursor(ON);
  201.  
  202.  free(temp);
  203.  return 0;
  204. }
  205.  
  206.  
  207. int cut_sprite(unsigned click_x, unsigned click_y)
  208. /* Adds a cut to the current list of cuts if the cut is not present yet */
  209. /* otherwise it cancels the cut renumbering all the list        */
  210. {
  211.  struct CUT *crsr= cut_list,
  212.             *last= NULL;
  213.  register unsigned counter= 0;
  214.  
  215.  
  216.  asm sti
  217.  mouse_cursor(OFF);
  218.  
  219.  if (!*source_name) return SOURCE_ERR; /* There's not source picture */
  220.  
  221.  xor_rect(click_x, click_y, cut_x_size, cut_y_size, CUT_COLOR);
  222.  /* Xors the cut on the screen                   */
  223.  /* So if it is present yet it will be cancelled */
  224.  /* else it will be drawn             */
  225.  
  226.  while (crsr)
  227.  {
  228.   if (crsr->x == click_x && crsr->y == click_y && crsr->width == cut_x_size
  229.       && crsr->height == cut_y_size) /* if the cut is present  ... */
  230.      {
  231.       if (last) last->next= crsr->next; /* ... unlink it from the list */
  232.       else cut_list= crsr->next;
  233.  
  234.       renumber_cut(crsr, counter); /* and renumber all the remaining */
  235.       free(crsr);
  236.       break;
  237.      };
  238.  
  239.   last= crsr;
  240.   crsr= crsr->next;
  241.   counter++;
  242.  }
  243.  
  244.  if (!crsr) /* if the cut is not present ...  */
  245.     {       /* ... add it on the list queue   */
  246.      if ( !(crsr= (struct CUT *)malloc(sizeof(struct CUT))) )
  247.         {
  248.          mouse_cursor(ON);
  249.          while (Mouse.Button);
  250.          return MEM_ERR;
  251.         };
  252.  
  253.      if (last) last->next= crsr;
  254.      else cut_list= crsr;
  255.  
  256.      crsr->next= NULL;
  257.      crsr->x= click_x;
  258.      crsr->y= click_y;
  259.      crsr->width= cut_x_size;
  260.      crsr->height= cut_y_size;
  261.      cut_number(click_x, click_y, counter);
  262.     };
  263.  
  264.  list_modified= 1;
  265.  mouse_cursor(ON);
  266.  while (Mouse.Button);
  267.  return 0;
  268. }
  269.  
  270.  
  271. int save_LST(unsigned ask)
  272. {
  273.  char *temp;
  274.  FILE *dest;
  275.  
  276.  if ( ask && ( !list_modified || Message_box(lst_msg, 60, 80, 1) <= 0 ) )
  277.   return 0;
  278.  
  279.  if (!cut_list) return 0;
  280.  
  281.  temp= (char *)malloc(MAXSTRINGLEN);
  282.  
  283.  if (Input_box(IO_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
  284.     {
  285.      free(temp);
  286.      return 0;
  287.     };
  288.  
  289.  dest= fopen(temp, "wb");
  290.  free(temp);
  291.  
  292.  fwrite(source_name, sizeof(source_name), 1, dest);
  293.  
  294.  return write_cuts(dest);
  295. }
  296.  
  297.  
  298. int load_LST()
  299. {
  300.  char *temp= (char *)malloc(MAXSTRINGLEN);
  301.  register int handle;
  302.  
  303.  save_LST(1);
  304.  
  305.  if (Input_box(IO_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
  306.     {
  307.      free(temp);
  308.      return 0;
  309.     };
  310.  
  311.  if ( (handle= open(temp, O_RDWR | O_BINARY)) == -1 )
  312.     {
  313.      error(FILE_ERR, temp);
  314.      free(temp);
  315.      return -1;
  316.     };
  317.  
  318.  read(handle, temp, MAXSTRINGLEN);
  319.  
  320.  if ( load_source(temp) ) {
  321.                            free(temp);
  322.                            return -1;
  323.                           };
  324.  
  325.  free(temp);
  326.  destroy_LST();
  327.  
  328.  return load_cuts(handle);
  329. }
  330.  
  331.  
  332. int save_SPR()
  333. /* Writes all the sprites' bitmaps to a file */
  334. {
  335.  FILE *spr_file;
  336.  char *temp;
  337.  unsigned char far *base;
  338.  struct CUT *crsr;
  339.  register unsigned row, col;
  340.  
  341.  if (!cut_list) return -1;
  342.  
  343.  temp= (char *)malloc(MAXSTRINGLEN);
  344.  
  345.  if (Input_box(SPR_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
  346.     {
  347.      free(temp);
  348.      return 0;
  349.     };
  350.  
  351.  spr_file= fopen(temp, "wb");
  352.  free(temp);
  353.  
  354.  crsr= cut_list;
  355.  while (crsr)
  356.  {
  357.  
  358.   fwrite(&crsr->height, sizeof(unsigned char), 2, spr_file);
  359.   base= &(source_pic.buffer[crsr->x + crsr->y * 320]);
  360.  
  361.   for (row= 0; row < crsr->height; row++)
  362.       {
  363.        for (col= 0; col < crsr->width; col++)
  364.            putc(base[col],spr_file);
  365.  
  366.        base += 320;
  367.       };
  368.  
  369.   crsr= crsr->next;
  370.  };
  371.  
  372.  return fclose(spr_file);
  373. }
  374.  
  375.  
  376. void destroy_LST()
  377. {
  378.  struct CUT *crsr= cut_list, *next;
  379.  
  380.  while (crsr)
  381.  {
  382.   next= crsr->next;
  383.   free(crsr);
  384.   crsr= next;
  385.  };
  386.  
  387.  cut_list= NULL;
  388. }
  389.  
  390. void Draw_cuts()
  391. {
  392.  struct CUT *crsr= cut_list;
  393.  register unsigned counter= 0;
  394.  
  395.  mouse_cursor(OFF);
  396.  
  397.  while (crsr)
  398.  {
  399.   xor_rect(crsr->x, crsr->y, crsr->width, crsr->height, CUT_COLOR);
  400.   cut_number(crsr->x, crsr->y, counter++);
  401.   crsr= crsr->next;
  402.  };
  403.  
  404.  mouse_cursor(ON);
  405. }
  406.